#include "subtitlerenderer.h"
#include "Common/fileoperations.h"

#include <GL/gl.h>
#include <GL/glu.h>
#include <iostream>
#include <assert.h>

using namespace std;

SubtitleRenderer::SubtitleRenderer()
: m_VerticalOffset(40)
, m_Width(0)
, m_Height(0)
, m_pFont(NULL)
{
    string fontPath = DATADIR"/glover/fonts/arial.ttf";
    m_pFont = new FTGLPolygonFont(fontPath.c_str());

    if (m_pFont->Error())
    {
        cerr << "Failed to open font: " << fontPath << endl;
        delete m_pFont;
        m_pFont = NULL;
    }
    else
    {
        m_pFont->FaceSize(24);
    }
}

SubtitleRenderer::~SubtitleRenderer()
{
    delete m_pFont;
}

void SubtitleRenderer::setWindowSize(int width, int height)
{
    m_Width = width;
    m_Height = height;
    m_VerticalOffset = m_Height / 5;
}

bool SubtitleRenderer::loadSubtitle(const string& filename)
{
    if ("srt" == FileOperations::getFileExtension(filename))
    {
        try
        {
            m_Subtitle.open(filename);
            return true;
        }
        catch (SubtitleException& e)
        {
            cout << e.what() << endl;
        }
    }

    return false;
}

void SubtitleRenderer::render(uint64 timestamp)
{
    if (m_CurrentSubtitleEntity == timestamp)
    {
        renderCurrentSubtitle();
    }
    else
    {
        if (m_Subtitle.getSubtitle(timestamp, m_CurrentSubtitleEntity))
        {
            renderCurrentSubtitle();
        }
    }
}

void SubtitleRenderer::renderCurrentSubtitle()
{
    if (!m_pFont)
    {
        return;
    }

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    gluOrtho2D(0, m_Width-1, 0, m_Height-1);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

    glDisable(GL_TEXTURE_2D);
    glPushAttrib(GL_LIGHTING_BIT | GL_MULTISAMPLE_BIT_ARB);
    glEnable(GL_MULTISAMPLE_ARB);

    glColor3f(1.f, 1.f, 1.f);

    float llx, lly, llz, urx, ury, urz;
    float lineOffset;

    m_pFont->BBox(m_CurrentSubtitleEntity.line1.c_str(), llx, lly, llz, urx, ury, urz);
    lineOffset = (m_Width - (urx - llx)) / 2.f;
    renderLine(lineOffset, static_cast<float>(m_VerticalOffset), m_CurrentSubtitleEntity.line1);

    if (!m_CurrentSubtitleEntity.line2.empty())
    {
        m_pFont->BBox(m_CurrentSubtitleEntity.line2.c_str(), llx, lly, llz, urx, ury, urz);
        lineOffset = (m_Width - (urx - llx)) / 2.f;
        renderLine(lineOffset, m_VerticalOffset - (ury - lly) - 10.f, m_CurrentSubtitleEntity.line2);
    }

    glPopAttrib();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    assert(!glGetError());
}

void SubtitleRenderer::renderLine(float xOffset, float yOffset, const std::string& line)
{
    glPushMatrix();
        // shadow
        glColor3f(0.f, 0.f, 0.f);
        glPushMatrix();
        glTranslatef(xOffset + 2, yOffset - 2, 0);
        m_pFont->Render(line.c_str());
        glPopMatrix();
        // actual sub
        glColor3f(1.f, 1.f, 1.f);
        glTranslatef(xOffset, yOffset, 0);
        m_pFont->Render(line.c_str());
    glPopMatrix();
}
